﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using DiscoveryLogic.Analytics.BusinessLogic;
using DiscoveryLogic.Analytics.BusinessLogic.Rules;
using DiscoveryLogic.Analytics.DataObjects;
using DiscoveryLogic.Analytics.DataObjects.Rules;
using DiscoveryLogic.Analytics.DataObjects.Visuals;
using DiscoveryLogic.Analytics.Modules.ClusterRules;
using DiscoveryLogic.Analytics.Modules.DedupRules;
using DiscoveryLogic.Analytics.Modules.ImportRules;
using DiscoveryLogic.Analytics.Modules.LinkRules;
using DiscoveryLogic.Analytics.UI.Common.Wizard;
using DiscoveryLogic.Common.Utilities;
using RuleBase=DiscoveryLogic.Analytics.DataObjects.Rules.RuleBase;

namespace DiscoveryLogic.Analytics.Modules.DataNavigation
{

    /// <summary>
    /// Interaction logic for RuleTreeView.xaml
    /// </summary>
    public partial class RuleTreeView : UserControl
    {
        //public static ObservableCollection<RulesByType> AllRules
        //    = new ObservableCollection<RulesByType>();

        public delegate void OnRuleSelected(RuleBase rule);
        public event OnRuleSelected RuleSelected;
        private RuleTreePresenter _Presenter;

        public RuleTreeView()
        {
            InitializeComponent();
            //List<RuleBase> rules = RuleManager.GetRulesByType(RuleType.Import, "../images/database.ico");
            //RulesByType rulesByType = new RulesByType(RuleType.Import, rules);
            //AllRules.Add(rulesByType);
        }

        public RuleTreeView(RuleTreePresenter presneter)
			: this()
		{
			_Presenter = presneter;
			_Presenter.View = this;
		}

        public void PopulateTreeView(ObservableCollection<RulesByType> allRules)
        {
            this.treeRules.ItemsSource = allRules;
            
        }

        private void treeRules_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if(e.NewValue !=null && e.NewValue.GetType().IsSubclassOf(typeof(RuleBase)))
            {
                RuleBase rule = e.NewValue as RuleBase;
                if (this.RuleSelected != null)
                    this.RuleSelected(rule);
            }
        }

        #region cmu
        private void cmu_NewImportRule_Click(object sender, RoutedEventArgs e)
        {
            ImportRuleEditor xlImporter = new ImportRuleEditor();
            xlImporter.ImportRuleDefined += new ImportRuleEditor.OnImportRuleDefined(xlImporter_ImportExcelRuleDefined);
            PopupWindow dialog = new PopupWindow();
            dialog.Content = xlImporter;
            dialog.SizeToContent = System.Windows.SizeToContent.WidthAndHeight;
            dialog.Title = "Import Rule Definition";
            dialog.ResizeMode = ResizeMode.CanResizeWithGrip;
            dialog.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            dialog.Show();
        }

        void xlImporter_ImportExcelRuleDefined(DiscoveryLogic.Analytics.DataObjects.Rules.EntityImportRule rule)
        {
            RuleManager.Save(rule);
            string dataSetName = System.IO.Path.GetFileNameWithoutExtension(rule.DataSourcePath);
            ImportRuleWorker worker = new ImportRuleWorker(rule, rule.DataSourcePath, dataSetName);
            List<EntityBase> entities = worker.RetrieveEntities();
            string iconPath = string.Empty;
            switch (rule.TgtEntityType)
            {
                case EntityType.Grants:
                    iconPath = "../images/tools.png";
                    break;
                case EntityType.Organizations:
                    iconPath = "../images/home.png";
                    break;
                case EntityType.Persons:
                    iconPath = "../images/user.png";
                    break;
                case EntityType.Publications:
                    iconPath = "../images/doc.png";
                    break;
            }
            EntityDataSet entityDataSet =
                new EntityDataSet(dataSetName, iconPath, rule.TgtEntityType,
                                  SetDataSourceType.ExcelFile, entities);
            entityDataSet.Save();
            MyData.ReadAllRules();
            MyData.ReadAllEntitySets();
        }

        private void cmu_NewLinkRule_Click(object sender, RoutedEventArgs e)
        {
            List<IWizardPageBase> wizPages = new List<IWizardPageBase>();
            LinkRuleInputEntityFieldMappings page1 = new LinkRuleInputEntityFieldMappings();
            LinkRuleSqlParameters page2 = new LinkRuleSqlParameters();
            LinkRuleTgtEntityFieldMappings page3=new LinkRuleTgtEntityFieldMappings();
            LinkRuleDistanceCalculator page4=new LinkRuleDistanceCalculator();

            page1.PrevPage = null;
            page1.NextPage = page2;

            page2.PrevPage = page1;
            page2.NextPage = page3;

            page3.PrevPage = page2;
            page3.NextPage = page4;

            page4.PrevPage = page3;
            page4.NextPage = null;

            wizPages.Add(page1);
            wizPages.Add(page2);
            wizPages.Add(page3);
            wizPages.Add(page4);
            EntityRelationRule rule = new EntityRelationRule(
                "Link Rule", "../images/rule.png",
                EntityType.Grants, EntityType.Publications, "");
            Dictionary<string,object> sharedVars=new Dictionary<string, object>();
            sharedVars.Add("LinkRule", rule);
            Wizard wiz = new Wizard(sharedVars, wizPages.ToArray(), page1);
            wiz.Finish += new Wizard.OnFinish(wizLinkRule_Finish);
            wiz.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            wiz.Show();
        }

        void wizLinkRule_Finish(Dictionary<string,object> wizVars)
        {
            EntityRelationRule rule = (EntityRelationRule) wizVars["LinkRule"];
            
            RuleManager.Save(rule);
            MyData.ReadAllRules();
        }

        private void cmu_NewDedupRule_Click(object sender, RoutedEventArgs e)
        {
            DedupRuleEditor dedupRuleEditor=new DedupRuleEditor();
            dedupRuleEditor.DedupRuleUpdated += new DedupRuleEditor.OnDedupRuleUpdated(dedupRuleEditor_DedupRuleUpdated);
            PopupWindow dialog = new PopupWindow();
            dialog.Content = dedupRuleEditor;
            dialog.SizeToContent = System.Windows.SizeToContent.WidthAndHeight;
            dialog.Title = "Dedup Rule Definition";
            dialog.ResizeMode = ResizeMode.CanResizeWithGrip;
            dialog.SizeToContent = SizeToContent.WidthAndHeight;
            dialog.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            dialog.Show();
        }

        private void cmu_NewClusterRule_Click(object sender, RoutedEventArgs e)
        {
            ClusterRuleEditor clusterRuleEditor = new ClusterRuleEditor();
            clusterRuleEditor.ClusterRuleUpdated += new ClusterRuleEditor.OnClusterRuleUpdated(clusterRuleEditor_ClusterRuleUpdated);
            PopupWindow dialog = new PopupWindow();
            dialog.Content = clusterRuleEditor;
            dialog.SizeToContent = System.Windows.SizeToContent.WidthAndHeight;
            dialog.Title = "Cluster Rule Definition";
            dialog.ResizeMode = ResizeMode.CanResizeWithGrip;
            dialog.SizeToContent = SizeToContent.WidthAndHeight;
            dialog.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            dialog.Show();
        }

        void clusterRuleEditor_ClusterRuleUpdated(EntityClusterRule rule)
        {
            MyData.ReadAllRules();
        }

        void dedupRuleEditor_DedupRuleUpdated(EntityDedupRule rule)
        {
            MyData.ReadAllRules();
        }

        private void cmu_OpenRule_Click(object sender, RoutedEventArgs e)
        {
            if(this.treeRules.SelectedValue is RuleBase)
            {
                RuleBase rule = (RuleBase) this.treeRules.SelectedValue;
                switch(rule.RuleType)
                {
                    case RuleType.Import:
                        EntityImportRule importRule = (EntityImportRule) rule;
                        ImportRuleEditor editor1 = new ImportRuleEditor(importRule);
                        editor1.ImportRuleDefined += new ImportRuleEditor.OnImportRuleDefined(xlImporter_ImportExcelRuleDefined);
                        PopupWindow dialog=new PopupWindow();
                        dialog.Content = editor1;
                        dialog.Show();
                        break;
                    case RuleType.Link:
                        List<IWizardPageBase> wizPages = new List<IWizardPageBase>();
                        LinkRuleInputEntityFieldMappings page1 = new LinkRuleInputEntityFieldMappings();
                        LinkRuleSqlParameters page2 = new LinkRuleSqlParameters();
                        LinkRuleTgtEntityFieldMappings page3 = new LinkRuleTgtEntityFieldMappings();
                        LinkRuleDistanceCalculator page4 = new LinkRuleDistanceCalculator();

                        page1.PrevPage = null;
                        page1.NextPage = page2;

                        page2.PrevPage = page1;
                        page2.NextPage = page3;

                        page3.PrevPage = page2;
                        page3.NextPage = page4;

                        page4.PrevPage = page3;
                        page4.NextPage = null;

                        wizPages.Add(page1);
                        wizPages.Add(page2);
                        wizPages.Add(page3);
                        wizPages.Add(page4);
                        EntityRelationRule relationRule = (EntityRelationRule) rule;
                        Dictionary<string, object> sharedVars = new Dictionary<string, object>();
                        sharedVars.Add("LinkRule", relationRule);
                        Wizard wiz = new Wizard(sharedVars, wizPages.ToArray(), page1);
                        wiz.Finish += new Wizard.OnFinish(wizLinkRule_Finish);
                        wiz.WindowStartupLocation = WindowStartupLocation.CenterScreen;
                        wiz.Finish +=new Wizard.OnFinish(wizLinkRule_Finish);
                        wiz.Show();
                        break;
                    case RuleType.Dedup:
                        EntityDedupRule dedupRule = (EntityDedupRule)rule;
                        DedupRuleEditor editor3 = new DedupRuleEditor(dedupRule);
                        editor3.DedupRuleUpdated += new DedupRuleEditor.OnDedupRuleUpdated(dedupRuleEditor_DedupRuleUpdated);
                        PopupWindow dialog3 = new PopupWindow();
                        dialog3.Content = editor3;
                        dialog3.SizeToContent = SizeToContent.WidthAndHeight;
                        dialog3.Show();
                        break;
                    case RuleType.Cluster:
                        EntityClusterRule clusterRule = (EntityClusterRule) rule;
                        ClusterRuleEditor editor4=new ClusterRuleEditor(clusterRule);
                        editor4.ClusterRuleUpdated += new ClusterRuleEditor.OnClusterRuleUpdated(editor4_ClusterRuleUpdated);
                        PopupWindow dialog4=new PopupWindow();
                        dialog4.Content = editor4;
                        dialog4.SizeToContent = SizeToContent.WidthAndHeight;
                        dialog4.WindowStartupLocation = WindowStartupLocation.CenterScreen;
                        dialog4.Show();
                        break;
                }
            }
        }

        void editor4_ClusterRuleUpdated(EntityClusterRule rule)
        {
            MyData.ReadAllRules();
        }

        private void cmu_DeleteRule_Click(object sender, RoutedEventArgs e)
        {
            if (this.treeRules.SelectedValue is RuleBase)
            {
                RuleBase rule = (RuleBase) this.treeRules.SelectedValue;
                RuleManager.DeleteRule(rule);
                MyData.ReadAllRules();
            }
        }

        private void cmu_RenameRule_Click(object sender, RoutedEventArgs e)
        {
        }

        private void cmuRules_Opened(object sender, RoutedEventArgs e)
        {
            this.cmuRules.Items.Clear();
            if(this.treeRules.SelectedValue is RuleBase)
            {
                MenuItem cmuOpenRule = new MenuItem();
                cmuOpenRule.Header = "Open rule";
                cmuOpenRule.Icon = this.LoadImage("/images/" + EntityIcons.OpenIcon, 16);
                cmuOpenRule.Click += new RoutedEventHandler(cmu_OpenRule_Click);
                this.cmuRules.Items.Add(cmuOpenRule);

                MenuItem cmuDelete=new MenuItem();
                cmuDelete.Header = "Delete rule";
                cmuDelete.Tag = this.LoadImage("/images/" + EntityIcons.DeleteIcon, 16);
                cmuDelete.Click +=new RoutedEventHandler(cmu_DeleteRule_Click);
                this.cmuRules.Items.Add(cmuDelete);
            }
            else
            {
                MenuItem cmuNewImportRule=new MenuItem();
                cmuNewImportRule.Header = "New import rule";
                cmuNewImportRule.Tag = "../images/import.png";
                cmuNewImportRule.Click += new RoutedEventHandler(cmu_NewImportRule_Click);
                MenuItem cmuNewLinkRule = new MenuItem();
                cmuNewLinkRule.Header = "New link rule";
                cmuNewLinkRule.Tag = "../images/link.png";
                cmuNewLinkRule.Click += new RoutedEventHandler(cmu_NewLinkRule_Click);
                MenuItem cmuNewDedupRule = new MenuItem();
                cmuNewDedupRule.Header = "New dedup rule";
                cmuNewDedupRule.Tag = "../images/dedup.png";
                cmuNewDedupRule.Click += new RoutedEventHandler(cmu_NewDedupRule_Click);
                MenuItem cmuNewClusterRule=new MenuItem();
                cmuNewClusterRule.Header = "New cluster rule";
                cmuNewClusterRule.Tag = EntityIcons.ClusterRuleIcon;
                cmuNewClusterRule.Click += new RoutedEventHandler(cmu_NewClusterRule_Click);
                this.cmuRules.Items.Add(cmuNewImportRule);
                this.cmuRules.Items.Add(cmuNewLinkRule);
                this.cmuRules.Items.Add(cmuNewDedupRule);
                this.cmuRules.Items.Add(cmuNewClusterRule);
            }
        }

        private Image LoadImage(string imagePath, double size)
        {
            Image image = new Image();
            image.Stretch = Stretch.None;
            image.Source = new BitmapImage(new Uri(imagePath, UriKind.RelativeOrAbsolute));
            image.SetValue(Image.WidthProperty, size);
            image.SetValue(Image.HeightProperty, size);
            return image;
        }
        #endregion

    }
}
